using System;
using UnityEditor;
using UnityEngine;

namespace LS.UnityExtensions.Editor
{
    public class TextInputWindow : EditorWindow
    {
        public static readonly float DefaultWidth = 150f;
        public static readonly float DefaultHeight = 150f;

        private static TextInputWindow m_Window;
        private static long s_LastClosedTime;

        private string text;
        private Action<string> m_OnTextInputAction = null;

        private static Styles m_Style;
        private static GUIStyle m_TextAreaStyle = new GUIStyle(EditorStyles.textArea)
        {
            wordWrap = true
        };

        class Styles
        {
            public GUIStyle background = "grey_border";
        }

        public static bool Show(Vector2 position, System.Action<string> onTextInput = null,string defaultText = null)
        {
            var wins = Resources.FindObjectsOfTypeAll(typeof(TextInputWindow));
            if (wins.Length > 0)
            {
                try
                {
                    ((EditorWindow)wins[0]).Close();
                    return false;
                }
                catch (Exception)
                {
                    m_Window = null;
                }
            }

            long nowMilliSeconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            bool justClosed = nowMilliSeconds < s_LastClosedTime + 50;

            if (!justClosed)
            {
                UnityEngine.Event.current.Use();

                if (m_Window == null)
                {
                    m_Window = CreateInstance<TextInputWindow>();
                    m_Window.hideFlags = HideFlags.HideAndDontSave;
                }

                m_Window.Init(position, onTextInput);
                return true;
            }
            return false;
        }

        private void OnEnable()
        {
            m_Window = this;
            text = string.Empty;
        }

        private void OnDisable()
        {
            s_LastClosedTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            m_Window = null;
            m_OnTextInputAction = null;
        }

        internal void OnGUI()
        {
            if (m_Style == null)
            {
                m_Style = new Styles();
            }
            GUI.Label(new Rect(0, 0, position.width, position.height), GUIContent.none, m_Style.background);
            GUILayout.Space(5);
            text = EditorGUILayout.TextArea(text, m_TextAreaStyle,GUILayout.Height(DefaultHeight - EditorGUIUtility.singleLineHeight - 20));
        
            GUILayout.Space(5);
            if (GUILayout.Button("Enter"))
            {
                m_OnTextInputAction?.Invoke(text);
                this.Close();
            }
        }

        private void OnLostFocus()
        {
            this.Close();
        }

        private void Init(Vector2 position, Action<string> onInput,string defaultText = null)
        {
            this.m_OnTextInputAction = onInput;
            position = GUIUtility.GUIToScreenPoint(position);
            var buttonRect = new Rect(position.x - DefaultWidth / 2, position.y - 16, DefaultWidth, 1);
            ShowAsDropDown(buttonRect, new Vector2(buttonRect.width, DefaultHeight));
            Focus();
            wantsMouseMove = true;
            if (!string.IsNullOrEmpty(defaultText))
            {
                text = defaultText;
            }
        }
    }
}

